package org.toves.checklua;

import java.util.ArrayList;
import java.util.List;

import org.toves.checklua.ast.AstNode;
import org.toves.checklua.ast.AstProcessor;
import org.toves.checklua.ast.Complaint;
import org.toves.checklua.parse.LuaParser;
import org.toves.checklua.parse.ParseException;
import org.toves.checklua.parse.TokenStream;
import org.toves.checklua.scan.LuaScanner;
import org.toves.checklua.scan.Token;
import org.toves.checklua.scan.TokenType;
import org.toves.checklua.warnings.UnknownReadProcessor;
import org.toves.checklua.warnings.UnreachableCodeProcessor;

public class Checker {
	private ArrayList<AstProcessor> processors;
	
	public Checker() {
		AstProcessor[] procs = {
				new UnreachableCodeProcessor(),
				new UnknownReadProcessor(),
		};

		processors = new ArrayList<AstProcessor>(procs.length);
		for (AstProcessor proc : procs) {
			processors.add(proc);
		}
	}
	
	public CheckerResult process(String text) {
		CheckerResult result = new CheckerResult();
		
		// scan the text
		LuaScanner scan = new LuaScanner();
		List<Token> tokens = scan.scan(text);
		boolean scanError = false;
		for (Token token : tokens) {
			if (token.getTokenType().isError()) {
				scanError = true;
				result.addComplaint(Complaint.createError(token,
						token.getTokenType().toString()));
			}
		}
		if (scanError) return result;
		
		// parse the text
		TokenStream stream = new TokenStream(tokens);
		AstNode root = LuaParser.buildTree(stream);
		try {
			stream.chomp(TokenType.TOKEN_EOF, "no additional information expected");
		} catch(ParseException e) { }
		for (Complaint err : stream.getComplaints()) {
			result.addComplaint(err);
		}
		if (root == null) return result;
		
		// process the syntax tree
		for (AstProcessor processor : processors) {
			result.addResult(processor.process(root));
		}
		return result;
		
	}
	
	public void reset() {
		for (AstProcessor processor : processors) {
			processor.reset();
		}
	}
	
	/*
	public static String performCheck(String text) {
		int newline = text.indexOf('\n');
		boolean multiline = newline >= 0 && newline < text.length() - 1;
		
		LuaScanner scan = new LuaScanner();
		List<Token> tokens = scan.scan(text);
		TokenStream stream = new TokenStream(tokens);
		LuaParser.buildTree(stream);
		try {
			stream.chomp(TokenType.TOKEN_EOF, "no additional information expected");
		} catch(ParseException e) { }

		for (ParseException err : stream.getErrors()) {
			Token t = err.getToken();
			String loc;
			if (multiline) {
				loc = t.getLine() + "." + t.getColumn();
			} else {
				loc = "" + t.getColumn();
			}
			err.printStackTrace();
			return loc + " \"" + t.getText(10) + "\": " + err.getMessage();
		}
		return null;
	}
	*/
}